﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using CoreEx.Common.Linq;
using LinFu.IoC.Configuration;

namespace CoreEx.Database.Linq.Implementation
{
    /// <summary>
    /// Rewrites the expression tree so that method call representing the 
    /// 'Equals' method is converted into a binary expression.
    /// </summary>
    [Implements(typeof(IExpressionRewriter), ServiceName = "EqualsRewriter")]
    public class EqualsRewriter : ExpressionVisitor, IExpressionRewriter
    {

        /// <summary>
        /// Rewrites the specified expression.
        /// </summary>
        /// <param name="expression">The expression to rewrite</param>
        /// <returns></returns>
        public Expression Rewrite(Expression expression)
        {
            return Visit(expression);
        }


        /// <summary>
        /// Visits the method call.
        /// </summary>
        /// <param name="m">The method being called</param>
        /// <returns><see cref="Expression"/></returns>
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m.Method.Name == "Equals")
            {
                Expression leftExpression = null;
                Expression rightExpression = null;
                
                //Static method call
                //e.g string.Equals("Somevalue","SomeOtherValue")
                if (m.Object == null)
                {
                    leftExpression = m.Arguments[0];
                    rightExpression = m.Arguments[1];
                }
                else
                {
                    leftExpression = m.Object;
                    rightExpression = m.Arguments[0];
                }

                var binaryExpression = Expression.MakeBinary(ExpressionType.Equal, leftExpression, rightExpression);
                return binaryExpression;
               
            }
            return base.VisitMethodCall(m);
        }
    }
}
